<script setup>
import { onMounted, nextTick, ref, reactive, watch, computed, watchEffect } from 'vue'
import { mapObj } from '../mapInfoObj/initMap';
import { getAstarLine, exportXlsx, getFile, getAstarLineA, getOutpng,getOutJson } from './astar.js'
import { ElMessage } from 'element-plus'
import { getNowDate } from '../../components/forecast/fore.js'
import * as turf from '@turf/turf'



let currentLines = []
onMounted(() => {
  nextTick(() => {
    // let p1 = L.circleMarker([36.11927, 120.565757],
    //   {
    //     color: 'red',
    //     radius: 5,
    //     fillOpacity: 1
    //   }).addTo(mapObj.map)

    // let p2 = L.circleMarker([36.089645, 120.330575],
    //   {
    //     color: 'red',
    //     radius: 5,
    //     fillOpacity: 1
    //   }).addTo(mapObj.map)

    // let p3 = L.circleMarker([35.382109, 119.561732],
    //   {
    //     color: 'red',
    //     radius: 5,
    //     fillOpacity: 1
    //   }).addTo(mapObj.map)

    let myIcon = L.icon({
      iconUrl: './img/location.png',
      iconSize: [20, 20],
      iconAnchor: [10, 10],
      popupAnchor: [0, -10],
    })
    // let marker = L.marker([36.0903, 120.3287], { icon: myIcon }).addTo(mapObj.map)
    // let text = L.marker([36.0903, 120.3287], {
    //   icon: L.divIcon({
    //     className: 'my-div-icon',
    //     html: '<div class="my-div-icon">起点</div>',
    //     iconSize: [45, 15],
    //     iconAnchor: [10, -15],
    //   })
    // }).addTo(mapObj.map)
  })

  //   lat: 36.0903,
  // lng: 120.3287
  // 添加起点图标


})
const start = ref({
  // lat: null,
  // lng: null
  // 36.0900 120.3287
  lat: 36.0903,
  lng: 120.3287
})
const end = ref({
  lat: null,
  lng: null
})
const midPoints = ref([])
const linesInfo = ref([])
let marker = null
const allLayer = {
  marker: [],
  startMarker: [],
  endMarker: [],
  line: [],
  lineA: [],
}

let lineInfo = ref([
  {
    name: 'A*',
    time: '',
    num: 0,
    gdNum: 0
  },
  {
    name: '改进A*',
    time: '',
    num: 0,
    gdNum: 0
  }
])

const outPng = () => {
  if (currentLines.length == 0) {
    return
  }
  let lines1 = currentLines.map(item => {
    let arr = item.split(',')
    return [Number(+arr[0]), Number(+arr[1])]
  })
  getOutpng({
    lines: lines1
  })
  return
  getOutpng({
    lines: currentLines
  }).then(res => {
    if (res.data.code == 200) {
      let name = res.data.data
      getFile({ name: `/png/${name}.png` }).then(res => {
        const a = document.createElement("a");
        a.href = URL.createObjectURL(res.data);
        a.download = name + ".png"
        a.click();
      })
    }
  })
}

const outJson = () => {
  if (currentLines.length == 0) {
    return
  }
  let lines1 = currentLines.map(item => {
    let arr = item.split(',')
    return [Number(+arr[0]), Number(+arr[1])]
  })
  getOutJson({
    lines: lines1
  })
}

const speed = ref(12)
const startT = ref(new Date()
  .toLocaleDateString()
  .split("/")
  .map((item) => {
    return item.length < 2 ? "0" + item : item;
  })
  .join("-"))


const endT = computed(() => {
  // 根据速度计算时间
  let time = lineLengthCom.value / speed.value
  let date = new Date(startT.value)
  date.setHours(date.getHours() + time)
  return date.toLocaleDateString()
    .split("/")
    .map((item) => {
      return item.length < 2 ? "0" + item : item;
    })
    .join("-")
})
let lineLength = ref([])
// 自定义图标
let myIcon = L.icon({
  iconUrl: './img/location.png',
  iconSize: [20, 20],
  iconAnchor: [10, 10],
  popupAnchor: [0, -10],
})
const handleSelect = (type) => {
  if (marker) {
    mapObj.map.removeLayer(marker)
    marker = null
    // mapObj.map.off('mousemove')
    mapObj.map.off('click')
    return
  }
  marker = L.marker([0, 0], { icon: myIcon }).addTo(mapObj.map)
  let str = ''
  let text = ''
  if (type == 'start') {
    str = '请选择起点'
    text = '起点'
  } else if (type == 'end') {
    str = '请选择终点'
    text = '终点'
  } else {
    str = '请选择途径点'
    text = `途径点${type + 1}`
  }
  marker.bindTooltip(str, {
    permanent: true,
    direction: 'top',
    className: 'marker-tooltip',
  }).openTooltip()
  mapObj.map.on('mousemove', (e) => {
    marker.setLatLng(e.latlng)
  })
  mapObj.map.on('click', (e) => {
    let { lat, lng } = e.latlng
    lat = lat.toFixed(4)
    lng = lng.toFixed(4)
    // let marker1 = L.marker([lat, lng], { icon: myIcon }).addTo(mapObj.map)
    // let text1 = L.marker([lat, lng], {
    //   icon: L.divIcon({
    //     className: 'my-div-icon',
    //     html: `<div class="my-div-icon">${text}</div>`,
    //     iconSize: [45, 15],
    //     iconAnchor: [10, -15],
    //   })
    // }).addTo(mapObj.map)
    // allLayer.marker.push(marker1, text1)
    if (type == 'start') {
      start.value.lat = lat
      start.value.lng = lng
    } else if (type == 'end') {
      end.value.lat = lat
      end.value.lng = lng
    } else {
      midPoints.value[type].lat = lat
      midPoints.value[type].lng = lng
    }
    mapObj.map.removeLayer(marker)
    marker = null
    // mapObj.map.off('mousemove')
    mapObj.map.off('click')
  })
}
const handleAdd = () => {
  midPoints.value.push({
    lat: null,
    lng: null
  })
},
  handleDelete = () => {
    midPoints.value.pop()
  },
  handleCreate = () => {
    lineLength.value = []
    let isOk = midPoints.value.some(item => {
      return item.lat == null || item.lng == null
    })
    if (start.value.lat == null || start.value.lng == null || end.value.lat == null || end.value.lng == null || isOk) {
      ElMessage.error('请选择坐标')
      return
    }
    let data = [start.value, ...midPoints.value, end.value]
    let allP = []
    data.forEach((item, idx) => {
      if (idx < data.length - 1) {
        let start = [Number(item.lat), Number(item.lng)]
        let end = [Number(data[idx + 1].lat), Number(data[idx + 1].lng)]
        allP.push(getAstarLine({
          start,
          end
        }))
      }
    })
    Promise.all(allP).then(res => {
      res.forEach((item, idx) => {
        let lines = item.data.data.all
        lines.unshift([Number(data[idx + 1].lat), Number(data[idx + 1].lng)])
        let itemLength = 0
        lines.forEach((line, index) => {
          if (index == lines.length - 1) return
          let l = L.latLng(line[0], line[1]).distanceTo(L.latLng(lines[index + 1][0], lines[index + 1][1]))
          itemLength += l
          // itemLength += L.latLng(line[0], line[1]).distanceTo(L.latLng(lines[index + 1][0], lines[index + 1][1]))
          // 计算方向
          let angle = Math.atan2(line[0] - lines[index + 1][0], line[1] - lines[index + 1][1]) * 180 / Math.PI
          linesInfo.value.push([line[0], line[1], lines[index + 1][0], lines[index + 1][1], angle, l / 1000 * 0.539956803456.toFixed(2)])
          let lines1 = L.polyline([
            [line[0], line[1]],
            [lines[index + 1][0], lines[index + 1][1]],
          ], {
            color: 'red',
            weight: 1.5,
          }).addTo(mapObj.map)
          allLayer.line.push(lines1)
        })
        // 0.539956803456
        lineLength.value.push(itemLength / 1000 * 0.539956803456.toFixed(2))
      })
    })
  },
  handleCreateHt = (type) => {
    lineLength.value = []
    let isOk = midPoints.value.some(item => {
      return item.lat == null || item.lng == null
    })
    if (start.value.lat == null || start.value.lng == null || end.value.lat == null || end.value.lng == null || isOk) {
      ElMessage.error('请选择坐标')
      return
    }
    let data = [start.value, ...midPoints.value, end.value]
    let allP = []
    data.forEach((item, idx) => {
      if (idx < data.length - 1) {
        let start = [Number(item.lat), Number(item.lng)]
        let end = [Number(data[idx + 1].lat), Number(data[idx + 1].lng)]
        // allP.push(getAstarLine({
        //   start,
        //   end
        // }))

        if (type == 'A') {
          allP.push(getAstarLineA({
            start,
            end
          }))
        } else {
          allP.push(getAstarLine({
            start,
            end
          }))
        }
      }
    })
    // allP.push(getAstarLine({
    //   start: [36.1886, 120.3519],
    //   end: [35.9210, 120.5652]
    // }))
    Promise.all(allP).then(res => {
      let lines = res[0].data.data.lines
      let t = res[0].data.data.t
      let num = res[0].data.data.num
      let gdNum = res[0].data.data.gdNum
      // var line = turf.lineString([
      //   ...lines.map(item => {
      //     let itemArr = item.split(',')
      //     return [+itemArr[0], +itemArr[1]]
      //   })
      // ]);
      // var curved = turf.bezierSpline(line);
      // // 绘制航线
      // curved.geometry.coordinates.forEach((item, idx) => {
      //   if (idx === curved.geometry.coordinates.length - 1) return
      //   let lines1 = L.polyline([
      //     [item[0], item[1]],
      //     [curved.geometry.coordinates[idx + 1][0], curved.geometry.coordinates[idx + 1][1]],
      //   ], {
      //     color: 'red',
      //     weight: 1.5,
      //   }).addTo(mapObj.map)
      //   allLayer.line.push(lines1)
      // })
      // let points = res[0].data.data.items
      // points.forEach((item, idx) => {
      //   if(idx%1 == 0) {
      //     let lat = item[1]
      //   let lng = item[2]
      //   let p = L.circleMarker([lat, lng], { 
      //     color: 'green',
      //     radius: 1.5,
      //     opacity: 1, 
      //     fillOpacity: 1 
      //   }).addTo(mapObj.map) 
      //   // allLayer
      //   allLayer.marker.push(p)
      //   p.bindTooltip(`${lat}，${lng}`, { 
      //     direction: 'top',
      //     className: 'marker-tooltip',
      //   })
      //   }
      // })


      currentLines = lines
      lines.forEach((item, idx) => {
        if (idx === lines.length - 1) return
        let start = item.split(',')
        let end = lines[idx + 1].split(',')
        let lines1 = L.polyline([
          [start[0], start[1]],
          [end[0], end[1]],
        ], {
          color: 'red',
          weight: 1.5,
        }).addTo(mapObj.map)
        if (type == 'A_HT') {
          allLayer.line.push(lines1)
          lineInfo.value[1].time = t
          lineInfo.value[1].num = num
          lineInfo.value[1].gdNum = gdNum
        } else {
          allLayer.lineA.push(lines1)
          lineInfo.value[0].time = t
          lineInfo.value[0].num = num
          lineInfo.value[0].gdNum = gdNum
        }
      })
    })
  },
  handleClear = () => {
    // allLayer.marker.forEach(item => {
    //   mapObj.map.removeLayer(item)
    // })
    // allLayer.line.forEach(item => {
    //   mapObj.map.removeLayer(item)
    // })

    for (let key in allLayer) {
      allLayer[key].forEach(item => {
        if (mapObj.map.hasLayer(item)) {
          mapObj.map.removeLayer(item)
        }
      })
    }
    allLayer.marker = []
    allLayer.line = []
    start.value = {
      lat: null,
      lng: null
    }
    end.value = {
      lat: null,
      lng: null
    }
    midPoints.value = []
    linesInfo.value = []
  },
  handleExport = () => {
    // console.log();
    let nowDate = getNowDate()
    let data = {}
    data.title = `航线${nowDate}`
    data.data = tableData.value
    exportXlsx(data).then(res => {
      if (res.data.code == 200) {
        let name = res.data.data
        getFile({ name: `/excel/${name}.xlsx` }).then(res => {
          const a = document.createElement("a");
          a.href = URL.createObjectURL(res.data);
          a.download = name + ".xlsx"
          a.click();
        })
      }
    })
  };
const lineLengthCom = computed(() => {
  let num = 0
  lineLength.value.forEach(item => {
    num += Number(item)
  })
  return num.toFixed(2)
})

const showLine = (item) => {
  if (item.name == 'A*') {
    allLayer.lineA.forEach(item => {
      if (mapObj.map.hasLayer(item)) {
        mapObj.map.removeLayer(item)
      } else {
        item.addTo(mapObj.map)
      }
    })
  } else {
    allLayer.line.forEach(item => {
      if (mapObj.map.hasLayer(item)) {
        mapObj.map.removeLayer(item)
      } else {
        item.addTo(mapObj.map)
      }
    })
  }
}

const tableData = computed(() => {
  return linesInfo.value.map(item => {
    return {
      start: `${item[0].toFixed(4)}\n${item[1].toFixed(4)}`,
      end: `${item[2].toFixed(4)}\n${item[3].toFixed(4)}`,
      angle: (+item[4]).toFixed(2) + '°',
      distance: item[5].toFixed(2) + '海里'
    }
  })
});

const gangkou = ref([
  {
    name: "青岛港",
    // lat: 36.0896,
    // lon: 120.3306,
    lat: 36.0904,
    lon: 120.3230,
  },
  {
    name: "日照港",
    // lat: 35.3821,
    // lon: 119.5617,
    lat: 35.3646,
    lon: 119.5501,
  },
  {
    name: "威海港",
    // lat: 36.1193,
    // lon: 120.5658,
    lat: 36.1158,
    lon: 120.5673,
  }
])

watch(start, (e) => {
  let { lat, lng } = e
  allLayer.startMarker.forEach(item => {
    mapObj.map.removeLayer(item)
  })
  if (lat && lng) {
    lat = Number(lat).toFixed(4)
    lng = Number(lng).toFixed(4)
    let marker1 = L.marker([lat, lng], { icon: myIcon }).addTo(mapObj.map)
    let text1 = L.marker([lat, lng], {
      icon: L.divIcon({
        className: 'my-div-icon',
        html: `<div class="my-div-icon">起点</div>`,
        iconSize: [45, 15],
        iconAnchor: [10, -15],
      })
    }).addTo(mapObj.map)
    allLayer.startMarker.push(marker1, text1)
  }

}, {
  deep: true
})


watch(end, (e) => {
  let { lat, lng } = e
  allLayer.endMarker.forEach(item => {
    mapObj.map.removeLayer(item)
  })
  if (lat && lng) {
    lat = Number(lat).toFixed(4)
    lng = Number(lng).toFixed(4)
    let marker1 = L.marker([lat, lng], { icon: myIcon }).addTo(mapObj.map)
    let text1 = L.marker([lat, lng], {
      icon: L.divIcon({
        className: 'my-div-icon',
        html: `<div class="my-div-icon">终点</div>`,
        iconSize: [45, 15],
        iconAnchor: [10, -15],
      })
    }).addTo(mapObj.map)
    allLayer.endMarker.push(marker1, text1)
  }

}, {
  deep: true
})

const setStart = (item) => {
  start.value.lat = item.lat
  start.value.lng = item.lon
}

const setEnd = (item) => {
  end.value.lat = item.lat
  end.value.lng = item.lon
}
</script>

<template>
  <div class="hcgh">
    <div style="width: 100%;">
      <div v-for="item in gangkou"
        style="margin: 5px;font-family: '幼圆';font-size: 18px;display: flex;align-items: center;">
        <div>
          <span>{{ item.name }}：</span>
          <span>{{ item.lat.toFixed(4) }}，{{ item.lon.toFixed(4) }}</span>
        </div>
        <div style="margin-left: auto;margin-right: 5px;">
          <el-button type="success" size="small" @click="setStart(item)">起点</el-button>
          <el-button type="warning" size="small" @click="setEnd(item)">终点</el-button>
        </div>

      </div>
    </div>
    <div class="hc_item">
      <span class="item_span">起始地：</span>
      <div class="item_inp">
        <el-input v-model="start.lat" placeholder="请输入纬度" style="padding: 0px 10px;"></el-input>
        -
        <el-input v-model="start.lng" placeholder="请输入经度" style="padding: 0px 10px;"></el-input>
      </div>
      <img src="../../assets/img/location.png" alt="" style="height: 20px;cursor: pointer;"
        @click="handleSelect('start')">
    </div>
    <div class="hc_item" v-for="(item, idx) in midPoints">
      <span class="item_span">途径点{{ idx + 1 }}：</span>
      <div class="item_inp">
        <el-input v-model="item.lat" placeholder="请输入纬度" style="padding: 0px 10px;"></el-input>
        -
        <el-input v-model="item.lng" placeholder="请输入经度" style="padding: 0px 10px;"></el-input>
      </div>
      <img src="../../assets/img/location.png" alt="" style="height: 20px;cursor: pointer;" @click="handleSelect(idx)">
    </div>
    <div class="hc_item">
      <span class="item_span">目的地：</span>
      <div class="item_inp">
        <el-input v-model="end.lat" placeholder="请输入纬度" style="padding: 0px 10px;"></el-input>
        -
        <el-input v-model="end.lng" placeholder="请输入经度" style="padding: 0px 10px;"></el-input>
      </div>
      <img src="../../assets/img/location.png" alt="" style="height: 20px;cursor: pointer;"
        @click="handleSelect('end')">
    </div>

    <div id="tools">
      <template v-if="linesInfo.length == 0">
        <!-- <el-button type="" style="margin-top: 10px;" @click="handleAdd">添加</el-button>
        <el-button type="" style="margin-top: 10px;" @click="handleDelete">移除</el-button> -->
        <el-button type="primary" style="margin-top: 10px;" @click="handleCreateHt('A')">A*</el-button>

        <el-button type="success" style="margin-top: 10px;" @click="handleCreateHt('A_HT')">改进A*</el-button>

      </template>
      <el-button type="danger" style="margin-top: 10px;" @click="handleClear">清除</el-button>
      <el-button type="success" style="margin-top: 10px;" @click="handleExport" v-if="linesInfo.length != 0">导出
      </el-button>
    </div>
    <div style="margin-top: 20px;flex: 1;">
      <!-- <div v-for="item in lineInfo"
        style="height: 50px;width: 100%;display: flex;align-items: center;justify-content: space-between;">
        <div style="width: 60px;">{{ item.name }}</div>
        <div>耗时：{{ item.time }}ms</div>
        <div style="margin-left: 10px;">节点数：{{ item.num }}</div>
        <el-button type="" size="default" @click="showLine(item)"
          style="margin-left: auto;margin-right: 5px;">显/隐</el-button>

      </div>
      <div v-if="lineInfo[0].time > 0 && lineInfo[1].time > 0" style="height: 50px;display: flex;align-items: center;">
        耗时缩短：{{ Number((lineInfo[0].time - lineInfo[1].time) / lineInfo[0].time * 100).toFixed(2) }}%
      </div>
      <div v-if="lineInfo[0].time > 0 && lineInfo[1].time > 0" style="height: 50px;display: flex;align-items: center;">
        搜索节点数减少：{{ Number((lineInfo[0].num - lineInfo[1].num) / lineInfo[0].num * 100).toFixed(2) }}%
      </div> -->

      <el-table :data="lineInfo" border stripe>
        <el-table-column prop="name" label="算法名称" />
        <el-table-column prop="time" label="耗时(ms)" />
        <el-table-column prop="num" label="搜索点数" />
        <el-table-column prop="gdNum" label="拐点数" />
      </el-table>

      <el-button type="primary" size="default" @click="outPng" style="margin: 10px 0px;">出图</el-button>
      <el-button type="primary" size="default" @click="outJson" style="margin: 10px 0px;">导出json</el-button>

      <div v-if="lineInfo[0].time > 0 && lineInfo[1].time > 0"
        style="height: 50px;display: flex;align-items: center;font-family: '钉钉进步体';font-size: 16px;">
        <span style="width: 130px;">耗时缩短：</span>
        {{ Number((lineInfo[0].time - lineInfo[1].time) / lineInfo[0].time * 100).toFixed(2) }}%
      </div>
      <div v-if="lineInfo[0].time > 0 && lineInfo[1].time > 0"
        style="height: 50px;display: flex;align-items: center;font-family: '钉钉进步体';font-size: 16px;">
        <span style="width: 130px;">搜索节点数减少：</span>
        {{ Number((lineInfo[0].num - lineInfo[1].num) / lineInfo[0].num * 100).toFixed(2) }}%
      </div>

      <div v-if="lineInfo[0].time > 0 && lineInfo[1].time > 0"
        style="height: 50px;display: flex;align-items: center;font-family: '钉钉进步体';font-size: 16px;">
        <span style="width: 130px;">拐点数减少：</span>
        {{ Number((lineInfo[0].gdNum - lineInfo[1].gdNum) / lineInfo[0].gdNum * 100).toFixed(2) }}%
      </div>

    </div>
    <div id="info" v-show="tableData.length > 0">
      <!-- 总海里 -->
      <el-table :data="tableData" style="width: 100%;height: 400px;">
        <el-table-column prop="start" label="起点">

          <template #default="scope">
            <div style="display: flex;flex-direction: column;">
              <span>{{ scope.row.start.split('\n')[0] }}</span>
              <span>{{ scope.row.start.split('\n')[1] }}</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="end" label="终点">

          <template #default="scope">
            <div style="display: flex;flex-direction: column;">
              <span>{{ scope.row.end.split('\n')[0] }}</span>
              <span>{{ scope.row.end.split('\n')[1] }}</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="distance" label="距离" />
        <el-table-column prop="angle" label="角度" />
      </el-table>
      <div class="t">
        <div class="t_item">
          <span style="font-family: '得意黑体';" class="item_title">总距离：</span>
          <span class="item_content">{{ lineLengthCom }}海里</span>
        </div>


        <div class="t_item">
          <span style="font-family: '得意黑体';" class="item_title">速度：</span>
          <el-input-number v-model="speed" :min="0" :max="100" :step="1" controls-position="right"
            style="width: 140px;"></el-input-number>
        </div>
        <div class="t_item">
          <span style="font-family: '得意黑体';">开始时间：</span>
          <el-date-picker v-model="startT" type="date" placeholder="选择日期时间" value-format="YYYY-MM-DD"
            style="width: 140px;"></el-date-picker>
        </div>
        <div class="t_item">
          <span style="font-family: '得意黑体';">结束时间：</span>
          <!-- <span>{{ lineLengthCom }}海里</span> -->
          <span>{{ endT }}</span>
        </div>
        <div class="t_item">
          <span style="font-family: '得意黑体';">用时：</span>
          <!-- <span>{{ lineLengthCom }}海里</span> -->
          <span>{{ (lineLengthCom / speed).toFixed(2) }}小时</span>
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="less" scoped>
.hcgh {
  display: flex;
  flex-direction: column;
  height: 100%;

  #tools {
    display: flex;
    justify-content: space-around;
    margin-top: 20px;

    .el-button {
      flex: 1;
    }
  }

  #info {
    flex: 1;
    display: flex;
    flex-direction: column;
  }

  .hc_item {
    margin-top: 15px;
    font-size: 16px;
    display: flex;
    align-items: center;
    justify-content: space-around;

    .item_span {
      width: 60px;
      font-family: '得意黑体';
    }

    .item_inp {
      display: flex;
      flex: 1;
      align-items: center;
    }
  }

  .t {
    margin-top: 10px;
    font-size: 16px;
    display: flex;
    flex-direction: column;

    .t_item {
      display: flex;
      // justify-content: center;
      justify-content: space-between;
      align-items: center;
      // margin-top: 10px;
      padding: 10px 10px;
      border-bottom: 1px solid var(--el-color-border-Darker);
    }
  }
}
</style>